/**
 * 实现vue的hash模式
 * instll： Vue.use() 调用install时传递两个参数，1.vue的构造函数， 2.可选对象
 * 
 */

let _Vue = null

 export default class VueRouter {
     static install(Vue) {
         // 1. 判断当前插件是否安装，如果已经安装就不需要重新安装，定义一个变量installed去判断
         if(VueRouter.install.installed) return false
         VueRouter.install.installed = true

         //2. 把构造函数vue记录到全局变量，install是静态方法，接收了一个vue构造函数，而在VueRouter的实例中还要使用构造函数，比如创建router-link，router-view时，需要调用Vue.component来创建
         _Vue = Vue

         //3.把创建Vue实例时候传入的router对象注入到vue实例上，
         _Vue.mixin({
             //通过beforeCreate去获取this，这里的this指向的是vue实例
             beforeCreate() {
                 //防止多次挂载，判断作用是只在页面才挂载，在组件便不挂载
                 if(this.$options.router) {
                     //只有页面才有$options.router这个选项
                     _Vue.prototype.$router = this.$options.router
                     this.$options.router.init()
                 }
             }
         })
     }

     
     constructor(options) {
        this.options = options
        // key：路由地址， value： 组件
        this.routeMap = {}
        //响应式对象，current记录当前路由地址，初始化路由也用到这里
        this.data = _Vue.observable({
            current: window.location.hash ? window.location.hash.slice(1, window.location.hash.length) : '/'
        })

        //当路由为/的时候，应该加上hash值#
        if(this.data.current === '/') {
            window.location.hash = "/"
        }
     }

     //将routes转换成key，value存到routeMap中
     createRouteMap() {
         for(let route of this.options.routes) {
             this.routeMap[route.path] = route.component 
         }
     }
     
     initComponents (Vue) {
         const self = this
         Vue.component('router-link', {
             props: {
                 to: String
             },
             render(h) {
               return h('a', {
                   attrs: {
                       href: this.to
                   },
                   on: {
                       click: this.clickHandleer
                   }
               },
               [this.$slots.default])
             },
             methods: {
                clickHandleer(e) {
                    // history.pushState('', '', this.to)
                    location.hash = this.to
                    this.$router.data.current = this.to
                    e.preventDefault() 

                }
             }
         })

         Vue.component("router-view", {
            render(h) {
                let component = self.routeMap[self.data.current]
                return h(component)
            }
         })
     }

     init () {
        this.createRouteMap() 
        this.initComponents(_Vue)
        this.initEvent()
    }

     initEvent () {
        //历史方式变化时触发
        // window.addEventListener('popstate', () => {
        //     this.data.current = window.location.pathname
        // })
       
        //监听路由变化，然后给current赋值，让routeMap进行匹配对应的组件
        window.addEventListener('hashchange', () => {
            this.data.current = window.location.hash ? window.location.hash.slice(1, window.location.hash.length) : '/'
        })
  
      }
 }